﻿#include <jsonDecode.h>

JsonDecode::JsonDecode() {
	
}

JsonDecode::~JsonDecode() {
	
}

//获取对应tree的值
QJsonValue JsonDecode::getJsonValue(Tree T) {
	QJsonValue value;
	JsonDirContent jsonDir = JsonDirContent(T);
	QJsonValue::Type type = jsonDir.getType();
	switch (type) {
	case QJsonValue::Object: {
		int length = getTreeChildrenLength(T);
		QJsonArray array;
		for (int i = 0; i < length; i++) {
			Tree child = atParentTree(T, i);
			QJsonValue childValue = getJsonValue(child);
			array.append(childValue);
		}
		value = QJsonValue(array);
		break;
	}
	case QJsonValue::Bool: {
		bool *boolean = (bool *)jsonDir.getValue();
		value = QJsonValue(*boolean);
		break;
	}
	case QJsonValue::Double: {
		double *real = (double *)jsonDir.getValue();
		value = QJsonValue(*real);
		break;
	}
	case QJsonValue::String: {
		QString *str = (QString *)jsonDir.getValue();
		value = QJsonValue(*str);
		break;
	}
	}
	return value;
}

//获取对应tree的完整路径key数组
QList<QString> JsonDecode::getCompleteDirKey(Tree T) {
	QList<QString> list;
	int depth = getTreeDepth(T);
	Tree tmp = T;
	//不包含root目录
	for (int i = 0; i < depth; i++) {
		if (tmp != NULL) {
			JsonDirContent jsonDir = JsonDirContent(tmp);
			QString key = jsonDir.getKey();
			list.append(key);
		}
		tmp = getTreeParent(tmp);
	}
	return list;
}

//获取对应tree的完整路径json设置值的指令数组
QByteArray JsonDecode::getCompleteDir(Tree T, QJsonValue value) {
	QList<QString> keyList = getCompleteDirKey(T);
	//判断当前值类型，并生成对应的value
	QJsonValue jsonValue;
	if (value != 0) {
		jsonValue = QJsonValue(value);
	}
	else {
		jsonValue = getJsonValue(T);
	}
	QJsonObject jsonObject;
	//键嵌套
	int keyLength = keyList.count();
	for (int i = 0; i < keyLength; i++) {
		QString key = keyList[i];
		QJsonObject tmpObject;
		if (i == 0) {
			tmpObject.insert(key, jsonValue);
		}
		else {
			tmpObject.insert(key, jsonObject);
		}
		jsonObject = tmpObject;
	}
	QByteArray byteArray = JsonConversion::getByteArrayFromJsonObject(jsonObject);
	return byteArray;
}

//在tree目录下解析jsonValue，这是一个递归函数
void JsonDecode::jsonValueUnpack(QJsonValue jsonValue, Tree T) {
	JsonDirContent *jsonDir = (JsonDirContent *)getTreeData(T);
	void *value = jsonDir->getValue();
	QJsonValue::Type type = jsonDir->getType();
	QString key = jsonDir->getKey();
	switch (jsonValue.type()) {
		case QJsonValue::Object: {
			if (type == QJsonValue::Object) {
				//存在子目录则递归到解析目录函数
				jsonTreeUnpack(jsonValue.toObject(), T);
			}
			break;
		}
		case QJsonValue::Bool: {
			if (type == QJsonValue::Bool) {
				bool *boolean = (bool *)value;
				*boolean = jsonValue.toBool();
				emit jsonDir->valueChanged(*jsonDir);
			}
			break;
		}
		case QJsonValue::Double: {
			if (type == QJsonValue::Double) {
				double *real = (double *)value;
				*real = jsonValue.toDouble();
				emit jsonDir->valueChanged(*jsonDir);
			}
			break;
		}
		case QJsonValue::String: {
			if (type == QJsonValue::String) {
				QString *str = (QString *)value;
				*str = jsonValue.toString();
				emit jsonDir->valueChanged(*jsonDir);
			}
			break;
		}
		case QJsonValue::Array: {
			if (type == QJsonValue::Object) {
				//array则当前函数递归
				int childLength = getTreeChildrenLength(T);
				QJsonArray array = jsonValue.toArray();
				int arrayLength = array.count();
				int minLength = qMin<int>(childLength, arrayLength);
				for (int i = 0; i < minLength; i++) {
					//获取子成员的值
					QJsonValue arrayValue = array.at(i);
					//递归到值解析
					Tree child = atParentTree(T, i);
					jsonValueUnpack(arrayValue, child);
				}
			}
			break;
		}
		case QJsonValue::Null: {
			break;
		}
	}
}

//在tree目录下解析json，这是一个递归函数
void JsonDecode::jsonTreeUnpack(QJsonObject json, Tree T) {
	QStringList keyList = json.keys();
	for (int i = 0; i < keyList.count(); i++) {
		int childLength = getTreeChildrenLength(T);
		for (int j = 0; j < childLength; j++) {
			Tree child = atParentTree(T, j);
			QString dirKey = JsonDirContent(child).getKey();
			if (dirKey == keyList[i]) {
				//解析值函数
				jsonValueUnpack(json.value(keyList[i]), child);
			}
		}
	}
}

//在tree目录下解析字符串
void JsonDecode::decodeString(QString str, Tree jsonTree) {
	QJsonObject jsonObject = JsonConversion::getJsonObjectFromString(str);
	jsonTreeUnpack(jsonObject, jsonTree);
}

//获取Tree的值类型
QJsonValue::Type JsonDecode::getTreeType(Tree tree) {
	JsonDirContent *jsonDir = (JsonDirContent *)getTreeData(tree);
	return jsonDir->getType();
}

//获取Tree内的key
QString JsonDecode::getTreeKey(Tree T) {
	JsonDirContent *content = (JsonDirContent *)getTreeData(T);
	return content->getKey();
}

//设置Tree内的dir
void JsonDecode::setTreeDir(Tree T, const QString dir) {
	JsonDirContent *content = (JsonDirContent *)getTreeData(T);
	content->setDir(dir);
}

//通过key找到Tree子成员
Tree JsonDecode::findTreeChildByKey(Tree parent, const QString key) {
	int childCount = getTreeChildrenLength(parent);
	for (int i = 0; i < childCount; i++) {
		Tree child = atParentTree(parent, i);
		if (getTreeKey(child) == key) {
			return child;
		}
	}
	return nullptr;
}

//为一个树的所有子目录添加dir信息，这是一个递归函数
void JsonDecode::addDirToTree(const QString path, Tree contentTree) {
	int childCount = getTreeChildrenLength(contentTree);
	for (int i = 0; i < childCount; i++) {
		Tree child = atParentTree(contentTree, i);
		QString key = getTreeKey(child);
		//添加内容的路径信息
		QString dir = "";
		dir += path + "/" + key;
		setTreeDir(child, dir);
		//如果当前是一个目录则递归
		if (QJsonValue::Object == getTreeType(child)) {
			addDirToTree(dir, child);
		}
	}
}

//为一个树更新dir信息
void JsonDecode::jsonDirUpdate(Tree tree) {
	QStringList dirList;
	int depth = getTreeDepth(tree);
	Tree tmp = tree;
	//不包含root目录
	for (int i = 0; i < depth; i++) {
		if (tmp != nullptr) {
			QString key = getTreeKey(tmp);
			dirList.append(key);
		}
		tmp = getTreeParent(tmp);
	}
	QString dir = "";
	int dirCount = dirList.count();
	for (int i = 0; i < dirCount; i++) {
		dir += "/" + dirList.takeLast();
	}
	//设置当前tree的路径信息
	setTreeDir(tree, dir);
	//拼接tree目录下子元素的路径信息
	addDirToTree(dir, tree);
}

//根据路径在root目录下获取路径的tree节点，如路径不存在则返回空
Tree JsonDecode::getTreeNodeByPaths(Tree root, const QString path) {
	QString s = "/";
	QStringList token = path.split(s);
	//浅拷贝树
	Tree parent = root;
	for (int i = 0; i < token.count(); i++) {
		if (token[i] != "") {
			//如果不存在此令牌，则返回空
			if (nullptr == findTreeChildByKey(parent, token[i])) {
				return nullptr;
			}
			//下一级父目录
			parent = findTreeChildByKey(parent, token[i]);
		}
	}
	//返回对应树
	return parent;
}

//在一个root目录中，根据路径添加jsonContent内容，如路径不存在会自动创建相关tree目录
void JsonDecode::appendJsonDir(Tree root, QString path, JsonDirContent *content) {
	QString s = "/";
	QStringList token = path.split(s);
	//浅拷贝树
	Tree parent = root;
	for (int i = 0; i < token.count(); i++) {
		if (token[i] != "") {
			//如果不存在此令牌，则创建目录
			if (nullptr == findTreeChildByKey(parent, token[i])) {
				//创建目录
				JsonDirContent *objContent = new JsonDirContent(token[i], nullptr, QJsonValue::Object);
				Tree objTree = newTree(objContent);
				if (nullptr != parent) {
					insertTree(parent, objTree);
				}
				//添加目录的路径信息
				jsonDirUpdate(objTree);
			}
			//下一级父目录
			parent = findTreeChildByKey(parent, token[i]);
		}
	}
	Tree contentTree = newTree(content);
	//添加成员到父目录
	if (nullptr != parent) {
		insertTree(parent, contentTree);
	}
	//添加内容树的路径信息
	jsonDirUpdate(contentTree);
}

//在一个root目录中，根据路径添加树内容，如路径不存在会自动创建目录
void JsonDecode::appendJsonDir(Tree root, QString path, Tree contentTree) {
	QString s = "/";
	QStringList token = path.split(s);
	//浅拷贝树
	Tree parent = root;
	for (int i = 0; i < token.count(); i++) {
		if (token[i] != "") {
			//如果不存在此令牌，则创建目录
			if (nullptr == findTreeChildByKey(parent, token[i])) {
				//创建目录
				JsonDirContent *objContent = new JsonDirContent(token[i], nullptr, QJsonValue::Object);
				Tree objTree = newTree(objContent);
				if (nullptr != parent) {
					insertTree(parent, objTree);
				}
				//添加目录的路径信息
				jsonDirUpdate(objTree);
			}
			//下一级父目录
			parent = findTreeChildByKey(parent, token[i]);
		}
	}
	//添加成员到父目录
	if (nullptr != parent) {
		insertTree(parent, contentTree);
	}
	//添加内容树的路径信息
	jsonDirUpdate(contentTree);
}

